package com.ea.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ea.admin.mapper.AdminAccountMapper;
import com.ea.admin.mapper.AdminCompanyPermissionMapper;
import com.ea.admin.mapper.CompanyInfoMapper;
import com.ea.admin.pojo.Enum.RoleCode;
import com.ea.admin.pojo.dto.CompanyDto;
import com.ea.admin.pojo.po.AdminAccount;
import com.ea.admin.pojo.po.AdminCompanyPermission;
import com.ea.admin.pojo.po.CompanyInfo;
import com.ea.admin.pojo.vo.account.ContactAdminVo;
import com.ea.admin.pojo.vo.company.CompanyVo;
import com.ea.admin.service.CompanyPermissionService;
import com.ea.common.result.BizException;
import com.ea.common.result.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CompanyPermissionServiceImpl implements CompanyPermissionService {
    @Resource
    AdminCompanyPermissionMapper adminCompanyPermissionMapper;
    @Resource
    CompanyInfoMapper companyInfoMapper;
    @Resource
    AdminAccountMapper adminAccountMapper;

    @Override
    public List<CompanyVo> getCompanyPermission(Long accountId) {
        int rootLevel = adminCompanyPermissionMapper.getMinLevelByAccountId(accountId);
        // 先获得用户管理的所有单位
        List<CompanyDto> allCompany = adminCompanyPermissionMapper.
                getSameLevelCompanyList(accountId, null);
        List<CompanyDto> rootCompany = new ArrayList<>();
        HashMap<Long, CompanyDto> queue = new HashMap<>();
        for (CompanyDto companyDto : allCompany) {
            List<CompanyDto> subCompanyList = new ArrayList<>();
            companyDto.setSubCompanyList(subCompanyList);
            if (companyDto.getLevel() == rootLevel) {
                rootCompany.add(companyDto);
            }
            queue.put(companyDto.getCompanyId(), companyDto);
            if (companyDto.getSupCompanyId() != null && queue.containsKey(companyDto.getSupCompanyId())) {
                CompanyDto supCompany = queue.get(companyDto.getSupCompanyId());
                supCompany.getSubCompanyList().add(companyDto);
            }
        }

        return parseCompanyDtoToVo(rootCompany);
    }

    @Override
    public List<Long> getCompanyIdList(Long accountId) {
        return adminCompanyPermissionMapper.getCompanyPermissionListByAccountId(accountId);
    }

    @Override
    public void addCompanyPermission(Long accountId, Long companyIdList) {
        AdminCompanyPermission adminCompanyPermission = new AdminCompanyPermission();
        adminCompanyPermission.setAccountId(accountId);
        adminCompanyPermission.setCompanyId(companyIdList);
        adminCompanyPermission.setIsDel(0);
        adminCompanyPermissionMapper.insert(adminCompanyPermission);
    }

    @Override
    public void addCompanyPermission(Long accountId, List<Long> companyIdList) {
        List<AdminCompanyPermission> adminCompanyPermissionList = new ArrayList<>();
        companyIdList.forEach(companyId -> {
            AdminCompanyPermission adminCompanyPermission = new AdminCompanyPermission();
            adminCompanyPermission.setAccountId(accountId);
            adminCompanyPermission.setCompanyId(companyId);
            adminCompanyPermission.setIsDel(0);
            adminCompanyPermissionList.add(adminCompanyPermission);
        });
        adminCompanyPermissionMapper.insertBatchSomeColumn(adminCompanyPermissionList);
    }

    @Override
    public void addCompanyPermission(List<Long> accountIdList, Long companyId) {
        List<AdminCompanyPermission> adminCompanyPermissionList = new ArrayList<>();
        accountIdList.forEach(accountId -> {
            AdminCompanyPermission adminCompanyPermission = new AdminCompanyPermission();
            adminCompanyPermission.setAccountId(accountId);
            adminCompanyPermission.setCompanyId(companyId);
            adminCompanyPermission.setIsDel(0);
            adminCompanyPermissionList.add(adminCompanyPermission);
        });
        adminCompanyPermissionMapper.insertBatchSomeColumn(adminCompanyPermissionList);
    }

    @Override
    public void deleteCompanyPermissionByAccountId(Long accountId) {
        LambdaQueryWrapper<AdminCompanyPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminCompanyPermission::getAccountId, accountId);
        adminCompanyPermissionMapper.delete(wrapper);

        // 清除单位联系人信息
        LambdaUpdateWrapper<CompanyInfo> companyInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        companyInfoLambdaUpdateWrapper.set(CompanyInfo::getContactAdminId, null)
                .eq(CompanyInfo::getContactAdminId, accountId);
        companyInfoMapper.update(null, companyInfoLambdaUpdateWrapper);
    }

    @Override
    public List<Long> getAdminId(Long companyId) {
        return adminCompanyPermissionMapper.
                get123AccountIdListByCompanyId(companyId);
    }

    /**
     * 检查单位是否存在以及权限是否正确
     */
    @Override
    public void checkCompanyPermission(Long accountId, Long companyId) {
        // 单位校验不校验部门管理员
        Long adminRoleIdTEMP = adminAccountMapper.selectById(accountId).getAdminRoleId();
        if(adminRoleIdTEMP== RoleCode.DEPT_SUPER_ADMIN.getCode().longValue()||
                adminRoleIdTEMP== RoleCode.DEPT_ADMIN.getCode().longValue()){
            return;
        }
        // 如果id为空，则检查是否是超管
        if (companyId == null) {
            // 检查是否是超管
            AdminAccount adminAccount = adminAccountMapper.selectById(accountId);
            if (adminAccount == null) {
                throw new BizException(ErrorCode.SYSTEM_RESOURCE_ADMIN_ACCOUNT_NOT_EXISTS);
            }
            Long adminRoleId = adminAccount.getAdminRoleId();
            if (adminRoleId != RoleCode.SUPER_ADMIN.getCode().longValue()) {
                throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN);
            }

            return;
        }

        // 检查单位是否存在
        LambdaQueryWrapper<CompanyInfo> companyWrapper = new LambdaQueryWrapper<>();
        companyWrapper.eq(CompanyInfo::getCompanyId, companyId);
        if (companyInfoMapper.selectCount(companyWrapper) == 0) {
            throw new BizException(ErrorCode.SYSTEM_RESOURCE_COMPANY_NOT_EXISTS);
        }

        // 是否拥有权限
        LambdaQueryWrapper<AdminCompanyPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminCompanyPermission::getCompanyId, companyId)
                .eq(AdminCompanyPermission::getAccountId, accountId)
                .eq(AdminCompanyPermission::getIsDel, 0);
        if (adminCompanyPermissionMapper.selectCount(wrapper) <= 0) {
            throw new BizException(ErrorCode.USER_COMPANY_PERMISSION_ERROR);
        }
    }

    @Override
    public boolean checkCompanyExists(Long companyId) {
        LambdaQueryWrapper<CompanyInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyInfo::getCompanyId, companyId);
        return companyInfoMapper.selectCount(wrapper) > 0;
    }

    @Override
    public void checkAccountCompany(Long accountId, Long companyId) {
        Long adminRoleId = adminAccountMapper.selectById(accountId).getAdminRoleId();

        checkCompanyPermission(accountId, companyId);

        Integer level = companyInfoMapper.selectById(companyId).getLevel();
        // 检查是否是一级单位 检查管理员角色是否为超级管理员
        if (level == 0
                && adminRoleId != RoleCode.SUPER_ADMIN.getCode().longValue()) {
            throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN);
        }
        // 不是一级单位，检查角色是否为单位超级管理员
        else if (level != 0
                && !(adminRoleId == RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()
                || adminRoleId == RoleCode.SUPER_ADMIN.getCode().longValue())) {
            throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_COMPANY_SUPER_ADMIN);
        }
    }

    @Override
    public List<ContactAdminVo> getAllAdminInfoByCompanyIdAndName(Long companyId, String contactName) {
        return adminCompanyPermissionMapper.getAllAdminInfoByCompanyIdAndName(companyId, contactName);
    }

    @Override
    public void checkIsCompanyContact(Long accountId) {
        LambdaQueryWrapper<CompanyInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyInfo::getContactAdminId, accountId);
        if (companyInfoMapper.selectCount(wrapper) > 0) {
            throw new BizException(ErrorCode.SYSTEM_RESOURCE_IS_COMPANY_CONTACT);
        }
    }

    @Override
    public void checkContactCompany(Long accountId, List<Long> companyPermissionList) {
        LambdaQueryWrapper<CompanyInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompanyInfo::getContactAdminId, accountId);
        List<CompanyInfo> companyInfoList = companyInfoMapper.selectList(wrapper);
        log.info("companyInfoList：{}", companyInfoList);
        // 去掉空
        if (companyInfoList == null || companyInfoList.isEmpty()) {
            return;
        }
        List<Long> set = companyInfoList.stream().map(CompanyInfo::getCompanyId)
                .filter(Objects::nonNull).collect(Collectors.toList());
        if (companyPermissionList == null || companyPermissionList.isEmpty() || !new HashSet<>(companyPermissionList).containsAll(set)) {
            throw new BizException(ErrorCode.USER_PARAM_ERROR_IS_DEPT_CONTACT);
        }
    }

    @Override
    public List<Long> getSubCompanyIdList(Long accountId, List<Long> companyIdList) {
        return adminCompanyPermissionMapper.getSubCompanyIdList(accountId, companyIdList);
    }

    private List<CompanyVo> parseCompanyDtoToVo(List<CompanyDto> companyDtoList) {
        List<CompanyVo> voList = new ArrayList<>();
        for (CompanyDto companyDto : companyDtoList) {
            CompanyVo companyVo = new CompanyVo();
            companyVo.setCompanyId(companyDto.getCompanyId().toString());
            companyVo.setCompanyName(companyDto.getCompanyName());
            if (companyDto.getSupCompanyId() != null) {
                companyVo.setSupCompanyId(companyDto.getSupCompanyId().toString());
                companyVo.setSupCompanyName(companyDto.getSupCompanyName());
            }
            if (companyDto.getContactAdminId() != null) {
                companyVo.setContactAdminId(companyDto.getContactAdminId().toString());
            }
            companyVo.setContactAdminName(companyDto.getContactAdminName());
            companyVo.setContactAdminPhoneNum(companyDto.getContactAdminPhoneNum());
            companyVo.setSubCompanyVoList(parseCompanyDtoToVo(
                    companyDto.getSubCompanyList()
            ));
            voList.add(companyVo);
        }
        return voList;
    }

}
